--- /dev/null
+/*
+
+ Support for "GeoGrid Viewer ascii overlay files".
+
+ Copyright (C) 2008 Olaf Klein (o.b.klein@gpsbabel.org).
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "defs.h"
+#include "inifile.h"
+#include "grtcirc.h"
+
+#define MYNAME "ggv_ovl"
+
+static
+arglist_t ggv_ovl_args[] = {
+ ARG_TERMINATOR
+};
+
+typedef enum {
+ OVL_SYMBOL_BITMAP = 1,
+ OVL_SYMBOL_TEXT,
+ OVL_SYMBOL_LINE,
+ OVL_SYMBOL_POLYGON,
+ OVL_SYMBOL_RECTANGLE,
+ OVL_SYMBOL_CIRCLE,
+ OVL_SYMBOL_TRIANGLE
+} OVL_SYMBOL_TYP;
+
+typedef enum {
+ OVL_COLOR_RED = 1, /* = 1 */
+ OVL_COLOR_LIME, /* = 2 */
+ OVL_COLOR_BLUE, /* = 3 */
+ OVL_COLOR_YELLOW, /* = 4 */
+ OVL_COLOR_BLACK, /* = 5 */
+ OVL_COLOR_WHITE, /* = 6 */
+ OVL_COLOR_7, /* = 7 (draws only a simple line) */
+ OVL_COLOR_FUCHSIA, /* = 8 */
+ OVL_COLOR_AQUA, /* = 9 */
+} OVL_COLOR_TYP;
+
+/* some hints:
+ # "col": color
+ # "group": 1 means NO GROUP
+ # "size": size in pixels PLUS 100
+ # "with":
+ # "zoom":
+ # "art": line-style
+ */
+static inifile_t *inifile;
+static gbfile *fout;
+
+static int symbol_ct; /* Number of symbols written */
+static int group_ct; /* Group number during write */
+static int track_ct, route_ct;
+static bounds all_bounds;
+static OVL_COLOR_TYP color;
+
+/*******************************************************************************
+* %%% global callbacks called by gpsbabel main process %%% *
+*******************************************************************************/
+
+static void
+ggv_ovl_rd_init(const char *fname)
+{
+ inifile = inifile_init(fname, MYNAME);
+ if (ini->unicode) cet_convert_init(CET_CHARSET_UTF8, 1);
+
+ route_ct = 0;
+ track_ct = 0;
+}
+
+static void
+ggv_ovl_rd_deinit(void)
+{
+ inifile_done(inifile);
+}
+
+static void
+ggv_ovl_read(void)
+{
+ int symbols;
+ int i;
+
+ symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1);
+
+ for (i = 1; i <= symbols; i++) {
+ int points;
+ OVL_SYMBOL_TYP type;
+ char symbol[32];
+
+ snprintf(symbol, sizeof(symbol), "Symbol %d", i);
+
+ type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0);
+ points = inifile_readint_def(inifile, symbol, "Punkte", -1);
+
+ switch(type) {
+
+ char coord[32];
+ waypoint *wpt;
+ char *cx;
+ int group;
+
+ case OVL_SYMBOL_LINE:
+ case OVL_SYMBOL_POLYGON:
+
+ if (!inifile_readint(inifile, symbol, "Group", &group)) group = -1;
+
+ if (points > 0) {
+ int j;
+ route_head *rte, *trk;
+
+ rte = trk = route_head_alloc();
+ if (group > 1) {
+ route_add_head(rte);
+ route_ct++;
+ xasprintf(&rte->rte_name, "Route %d", route_ct);
+ }
+ else {
+ track_add_head(trk);
+ track_ct++;
+ xasprintf(&trk->rte_name, "Track %d", track_ct);
+ }
+
+ for (j = 0; j < points; j++) {
+
+ wpt = waypt_new();
+
+ snprintf(coord, sizeof(coord), "YKoord%d", j);
+ if ((cx = inifile_readstr(inifile, symbol, coord)))
+ wpt->latitude = atof(cx);
+ else
+ continue;
+
+ snprintf(coord, sizeof(coord), "XKoord%d", j);
+ if ((cx = inifile_readstr(inifile, symbol, coord)))
+ wpt->longitude = atof(cx);
+ else
+ continue;
+
+ if (group > 1) route_add_wpt(rte, wpt);
+ else track_add_wpt(trk, wpt);
+ }
+ }
+ break;
+
+ case OVL_SYMBOL_CIRCLE:
+ case OVL_SYMBOL_TRIANGLE:
+
+ wpt = waypt_new();
+ wpt->shortname = xstrdup(symbol);
+
+ if ((cx = inifile_readstr(inifile, symbol, "YKoord")))
+ wpt->latitude = atof(cx);
+ else
+ continue;
+ if ((cx = inifile_readstr(inifile, symbol, "XKoord")))
+ wpt->longitude = atof(cx);
+ else
+ continue;
+
+ waypt_add(wpt);
+ break;
+
+ case OVL_SYMBOL_BITMAP:
+ case OVL_SYMBOL_TEXT:
+ case OVL_SYMBOL_RECTANGLE: break;
+ }
+ }
+}
+
+/**************************************************************************/
+
+/* prototypes used in main functions */
+
+static void waypt_disp_cb(const waypoint *wpt);
+static void track_disp_cb(const route_head *trk);
+static void route_disp_cb(const route_head *rte);
+static void write_bounds(void);
+static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt);
+static int get_direction(const waypoint *A, const waypoint *B);
+// static void draw_symbol_text(const char *text, const waypoint *reference);
+
+/* -----------------------------------------------------------------------*/
+
+static void
+ggv_ovl_wr_init(const char *fname)
+{
+ fout = gbfopen(fname, "w", MYNAME);
+
+ symbol_ct = 0;
+}
+
+static void
+ggv_ovl_wr_deinit(void)
+{
+ gbfclose(fout);
+}
+
+static void
+ggv_ovl_write(void)
+{
+ group_ct = 1; /* tracks are not grouped */
+ color = OVL_COLOR_FUCHSIA;
+ track_disp_all(track_disp_cb, NULL, NULL);
+
+ group_ct++;
+ color = OVL_COLOR_AQUA;
+ route_disp_all(route_disp_cb, NULL, NULL);
+
+ group_ct++;
+ color = OVL_COLOR_LIME;
+ waypt_disp_all(waypt_disp_cb);
+
+ gbfprintf(fout, "[Overlay]\n");
+ gbfprintf(fout, "Symbols=%d\n", symbol_ct);
+ gbfprintf(fout, "[MapLage]\n");
+ gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n");
+ gbfprintf(fout, "DimmFc=100\n");
+ gbfprintf(fout, "ZoomFc=100\n");
+ write_bounds();
+ gbfprintf(fout, "RefOn=0\n"); /* no reference point */
+}
+
+/**************************************************************************/
+
+static void
+waypt_disp_cb(const waypoint *wpt)
+{
+ draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt);
+ gbfprintf(fout, "Width=20\n");
+ gbfprintf(fout, "Height=20\n");
+ gbfprintf(fout, "Dir=100\n");
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=102\n");
+ gbfprintf(fout, "Area=2\n");
+// draw_symbol_text(wpt->shortname, wpt);
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+track_disp_cb(const route_head *trk)
+{
+ int i;
+ queue *elem, *tmp;
+ int waypt_ct = trk->rte_waypt_ct;
+
+ if (waypt_ct <= 0) return;
+
+ draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL);
+
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=105\n");
+ gbfprintf(fout, "Punkte=%d\n", waypt_ct);
+
+ i = 0;
+
+ QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) {
+
+ waypoint *wpt = (waypoint *) elem;
+
+ gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude);
+ gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude);
+
+ i++;
+ }
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+route_disp_cb(const route_head *rte)
+{
+ int i;
+ queue *elem, *tmp;
+ waypoint *prev;
+ int waypt_ct = rte->rte_waypt_ct;
+
+ if (waypt_ct <= 0) return;
+
+ track_disp_cb(rte); /* draw a line as tracks */
+
+ color = OVL_COLOR_RED;
+
+ i = 0;
+ prev = NULL;
+
+ QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) {
+
+ waypoint *wpt = (waypoint *) elem;
+
+ if (prev != NULL) {
+ draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, 9 /* color */, prev);
+
+ gbfprintf(fout, "Width=12\n");
+ gbfprintf(fout, "Height=8\n");
+ gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt));
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=101\n");
+ gbfprintf(fout, "Area=2\n");
+ }
+
+ i++;
+ prev = wpt;
+ }
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+waypt_bound_calc(const waypoint *waypointp)
+{
+ waypt_add_to_bounds(&all_bounds, waypointp);
+}
+
+static void
+write_bounds(void)
+{
+ waypt_init_bounds(&all_bounds);
+
+ waypt_disp_all(waypt_bound_calc);
+ route_disp_all(NULL, NULL, waypt_bound_calc);
+ track_disp_all(NULL, NULL, waypt_bound_calc);
+
+ if (waypt_bounds_valid(&all_bounds)) {
+
+ double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2);
+ double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2);
+
+ gbfprintf(fout, "CenterLat=%0.8f\n", cx);
+ gbfprintf(fout, "CenterLong=%0.8f\n", cy);
+ }
+ else {
+ gbfprintf(fout, "CenterLong=10.52374295\n");
+ gbfprintf(fout, "CenterLat=52.26474445\n");
+ }
+}
+
+static void
+draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt)
+{
+ symbol_ct++;
+
+ gbfprintf(fout, "[Symbol %d]\n", symbol_ct);
+ gbfprintf(fout, "Typ=%d\n", typ);
+ gbfprintf(fout, "Group=%d\n", group_ct);
+ gbfprintf(fout, "Col=%d\n", color);
+ if (art >= 0) gbfprintf(fout, "Art=%d\n", art);
+ if (wpt) {
+ gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude);
+ gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude);
+ }
+}
+
+/* the following code comes from first overlay module */
+
+static int
+get_direction(const waypoint *A, const waypoint *B)
+{
+ double lata, lona, latb, lonb;
+ double dist, dir;
+ int res;
+
+ lata = RAD(A->latitude);
+ lona = RAD(A->longitude);
+ latb = RAD(B->latitude);
+ lonb = RAD(B->longitude);
+
+ dist = gcdist(lata, lona, latb, lonb);
+ dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist)));
+ if (lonb < lona) dir = -dir;
+ res = (int) DEG(dir);
+ res = 360 - (res + 270);
+ if (res < 0) res += 360;
+ else if (res > 360) res -= 360.0;
+
+ return res;
+}
+
+#if 0
+static void
+draw_symbol_text(const char *text, const waypoint *reference)
+{
+ waypoint wpt;
+
+ if ((reference == NULL) || (text == NULL)) return;
+ if (*text == '\0') return;
+
+ wpt = *reference;
+
+ wpt.latitude = wpt.latitude + 0.015;
+ wpt.longitude = wpt.longitude + 0.015;
+
+ draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt);
+
+ gbfprintf(fout, "Area=1\n");
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=120\n");
+ gbfprintf(fout, "Font=3\n");
+ gbfprintf(fout, "Dir=100\n");
+ gbfprintf(fout, "Text=%s\n", text);
+}
+#endif
+
+/**************************************************************************/
+
+ff_vecs_t ggv_ovl_vecs = {
+ ff_type_file,
+ FF_CAP_RW_ALL,
+ ggv_ovl_rd_init,
+ ggv_ovl_wr_init,
+ ggv_ovl_rd_deinit,
+ ggv_ovl_wr_deinit,
+ ggv_ovl_read,
+ ggv_ovl_write,
+ NULL,
+ ggv_ovl_args,
+ CET_CHARSET_MS_ANSI, 0
+};
+
+/**************************************************************************/